package com.exonline.back.controller.login;

import com.exonline.commons.entity.Manager;
import com.exonline.commons.utils.LogincheckUtils;
import com.exonline.commons.utils.TokenUtils;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

/**
 * @desc 登录模块控制器
 * 该类负责处理与登录、注册和注销相关的请求。
 * 包括登录、注册、登出操作。
 * @author hbrj
 */
@WebServlet("/admin/login")
public class LoginServlet extends HttpServlet {

    ObjectMapper mapper = new ObjectMapper(); // 用于转换 Java 对象为 JSON 格式
    LoginService service = new LoginService(); // 登录服务层对象

    /**
     * @desc 1.处理 HTTP 请求方法
     * 根据请求中的 "method" 参数调用相应的处理方法：登录、注销。
     *
     * @param req  HttpServletRequest 请求对象
     * @param resp HttpServletResponse 响应对象
     * @throws ServletException 如果请求处理出现错误
     * @throws IOException 如果响应时出现错误
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String method = req.getParameter("method"); // 获取请求方法
        try {
            if ("login".equals(method)) {
                this.login(req, resp); // 调用登录处理方法
            } else if ("logout".equals(method)) {
                this.logout(req, resp); // 调用注销处理方法
            }
        } catch (Exception e) {
            throw new ServletException("登录模块出现错误,错误信息:" + e.getMessage(), e);
        }
    }

    /**
     * @desc 2.处理注销请求,使当前用户会话无效
     * @param req  HttpServletRequest 请求对象
     * @param resp HttpServletResponse 响应对象
     * @throws IOException 如果响应时出现错误
     */
    private void logout(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.getSession().invalidate(); // 销毁当前会话
        resp.sendRedirect("http://36.235.128.117:26398/exonline_front/backstage/backstage/index.html"); // 重定向登录页
        Map<String,Object> map = new HashMap<>();
        map.put("code", 400);
        map.put("msg", "退出成功");
        map.put("data", req.getSession().getId());
        mapper.writeValue(resp.getWriter(), map); // 返回失败响应
        return;
    }


    /**
     * @desc 3.处理登录请求,验证用户名和密码，登录成功后返回用户信息及 Token。
     * @param req  HttpServletRequest 请求对象
     * @param resp HttpServletResponse 响应对象
     * @throws SQLException 如果数据库操作出现错误
     * @throws IOException 如果响应时出现错误
     * @throws NoSuchAlgorithmException 如果密码加密算法不存在
     */
    private void login(HttpServletRequest req, HttpServletResponse resp) throws SQLException, IOException, NoSuchAlgorithmException {
        String name = req.getParameter("name"); // 获取用户名
        String password = req.getParameter("password"); // 获取密码

        Map<String, Object> map = new HashMap<>();
        if (!LogincheckUtils.checkAdminLogin(name, password)) {
            map.put("code", 400);
            map.put("msg", "登录失败,用户名或密码格式错误");
            map.put("data", name + ":" + password);
            mapper.writeValue(resp.getWriter(), map); // 返回失败响应
            return;
        }

        Manager manager = (Manager) service.login(name, password); // 调用服务层进行登录操作
        if (manager != null) {
            map.put("code", 200);
            map.put("msg", "登录成功");
            map.put("data", manager); // 返回用户信息
            String token = TokenUtils.createToken(manager.getId(), manager.getAname()); // 生成登录 Token
            HttpSession session = req.getSession();
            session.setAttribute("token", token);
            map.put("token", token); // 返回 Token
            mapper.writeValue(resp.getWriter(), map); // 返回成功响应
        } else {
            map.put("code", 401);
            map.put("msg", "登录失败");
            map.put("data", manager);
            mapper.writeValue(resp.getWriter(), map); // 返回失败响应
        }
    }
}
